#include <iostream>
#include <memory>

// 工厂模式的三种类型

class Fruit
{
public:
    virtual void name()
    {}
};

class Apple : public Fruit
{
    void name() override
    {
        std::cout << "我是一个苹果" << std::endl;
    }
};

class Banana : public Fruit
{
    void name() override
    {
        std::cout << "我是一个香蕉" << std::endl;
    }
};

class Animal
{
public:
    virtual void name(){}
};

class Dog:public Animal
{
    void name()override
    {
        std::cout << "我是一只小狗" << std::endl;
    }
};

class Cat:public Animal
{
    void name()override
    {
        std::cout << "我是一只小猫" << std::endl;
    }
};

// class FruitFactor
// {
// public:
//     static std::shared_ptr<Fruit> Create(const std::string &name)
//     {
//         if (name == "苹果")
//         {
//             return std::make_shared<Apple>();
//         }
//         else if (name == "香蕉")
//         {
//             return std::make_shared<Banana>();
//         }
//         else{
//             return nullptr;
//         }
//     }
// };

// class FruitFactor
// {
// public:
//     virtual std::shared_ptr<Fruit> Create() = 0;
// };

class Factor
{
public:
    virtual std::shared_ptr<Fruit> GetFruit(const std::string& name) = 0;
    virtual std::shared_ptr<Animal> GetAnimal(const std::string& name) = 0;
};

class FruitFactor:public Factor
{
public:
    std::shared_ptr<Fruit> GetFruit(const std::string& name)override
    {
        if (name == "苹果")
        {
            return std::make_shared<Apple>();
        }
        else if (name == "香蕉")
        {
            return std::make_shared<Banana>();
        }
        else{
            return std::make_shared<Fruit>();
        }
    }
    std::shared_ptr<Animal> GetAnimal(const std::string& name)override
    {
        return std::make_shared<Animal>();
    }
};

class AnimalFactor:public Factor
{
public:
    std::shared_ptr<Fruit> GetFruit(const std::string& name)override
    {
        return std::make_shared<Fruit>();
    }
    std::shared_ptr<Animal> GetAnimal(const std::string& name)override
    {
        if (name == "小狗")
        {
            return std::make_shared<Dog>();
        }
        else if (name == "小猫")
        {
            return std::make_shared<Cat>();
        }
        else{
            return std::make_shared<Animal>();
        }
    }
};

class FactoryProducer
{
public:
    static std::shared_ptr<Factor> Create(const std::string& name)
    {
        if(name == "水果")
        {
            return std::make_shared<FruitFactor>();
        }
        else if(name == "动物")
        {
            return std::make_shared<AnimalFactor>();
        }
        else
        {
            return nullptr;
        }
    }
};

// class AppleFactor:public FruitFactor
// {
// public:
//     std::shared_ptr<Fruit> Create()override
//     {
//         return std::make_shared<Apple>();
//     }
// };

// class BananaFactor:public FruitFactor
// {
// public:
//     std::shared_ptr<Fruit> Create()override
//     {
//         return std::make_shared<Banana>();
//     }
// };

int main()
{
    std::shared_ptr<Factor> ff = FactoryProducer::Create("水果");
    std::shared_ptr<Fruit> fruit = ff->GetFruit("苹果");
    fruit->name();
    fruit = ff->GetFruit("香蕉");
    fruit->name();

    std::shared_ptr<Factor> fa = FactoryProducer::Create("动物");
    std::shared_ptr<Animal> animal = fa->GetAnimal("小狗");
    animal->name();
    animal = fa->GetAnimal("小猫");
    animal->name();


    // std::shared_ptr<FruitFactor> ff(new AppleFactor());
    // std::shared_ptr<Fruit> fruit = ff->Create();
    // fruit->name();

    // ff.reset(new BananaFactor());
    // fruit = ff->Create();
    // fruit->name();

    // static std::shared_ptr<Fruit> fruit = FruitFactor::Create("苹果");
    // fruit->name();

    // fruit = FruitFactor::Create("香蕉");
    // fruit->name();

    return 0;
}